﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Web.Security;
using GestaoContas.LigacaoBD;
using System.Data.SqlClient;
using System.Data.SqlServerCe;

namespace GestaoContas
{
    public partial class Conta : Form
    {
        private bool criar = false;
        private FicheiroConfiguracao _connectionString;

        private string _nome;

        public string Nome
        {
            get { return _nome; }
            set { _nome = value; }
        }

        private string _morada;

        public string Morada
        {
            get { return _morada; }
            set { _morada = value; }
        }

        private int _telefone;

        public int Telefone
        {
            get { return _telefone; }
            set { _telefone = value; }
        }

        private int _telemovel;

        public int Telemovel
        {
            get { return _telemovel; }
            set { _telemovel = value; }
        }

        private string _email;

        public string Email
        {
            get { return _email; }
            set { _email = value; }
        }

        private int _contribuinte;

        public int Contribuinte
        {
            get { return _contribuinte; }
            set { _contribuinte = value; }
        }

        private string _tipoConta;

        public string TipoConta
        {
            get { return _tipoConta; }
            set { _tipoConta = value; }
        }

        private string _user;

        public string User
        {
            get { return _user; }
            set { _user = value; }
        }

        private string _password;

        public string Password
        {
            get { return _password; }
            set { _password = value; }
        }

        /// <summary>
        /// Construtor para criar uma conta
        /// </summary>
        public Conta()
        {
            InitializeComponent();
            criar = true;
            _connectionString = new FicheiroConfiguracao();
            PreencheComboBoxTipoConta();

        }

        /// <summary>
        /// Construtor para alterar ou ver a conta
        /// </summary>
        /// <param name="alterar">True (para alterar), False (para ver)</param>
        public Conta(Boolean alterar)
        {
            InitializeComponent();
            _connectionString = new FicheiroConfiguracao();
        }

        /*********************************************************************************************
         * Valores a serem usados na validação da conta, quando a dialog box fecha
         * Se os campos do telefone e telemóvel estiverem vazios, as suas propriedades tomam o valor 0
         * Se o nº de contribuinte estiver inválido a sua propriedade também toma o valor 0
         * Caso a password não estiver idêntica a sua propriedade é nula
         * *******************************************************************************************/
        private void buttonOk_Click(object sender, EventArgs e)
        {
            if (criar)
            {
                bool userCriado = true;

                if (maskedTextBoxPassword.Text == maskedTextBoxConfirmaPassword.Text)
                {
                    /*************************************
                     *  CRIAÇÃO DA CONTA NA BD DE LOGIN  *
                     * ***********************************/
                    try
                    {
                        if (textBoxEmail.Text != null)  // se tiver email inserido, é usado na criação da conta
                        {
                            Membership.CreateUser(textBoxUser.Text, maskedTextBoxPassword.Text, textBoxEmail.Text);
                        }
                        else
                        {
                            Membership.CreateUser(textBoxUser.Text, maskedTextBoxPassword.Text);
                        }
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show(ex.Message, "Erro!", MessageBoxButtons.OK, MessageBoxIcon.Error);
                        userCriado = false;
                    }

                    /*****************************************************************
                     * CRIAÇÃO DO REGISTO DO UTILIZADOR NA BD DO JARDIM DE INFANCIA  *
                     * ***************************************************************/
                    if (userCriado)
                    {
                        bool pessoaCriada = true;
                        string connectionString = "Data Source=" + _connectionString.GetConnectionStringBd();
                        string insertString = @"INSERT INTO Pessoa (Nome, Morada, Telefone, Telemovel, Email, NumeroContribuinte, Role_fk, Userid) ";
                        insertString += "VALUES (@nome, @morada, @telefone, @telemovel, @email, @numerocontribuinte, @role_fk, @userid)";

                        try
                        {
                            SqlCeConnection conn = new SqlCeConnection(connectionString);
                            conn.Open();
                            SqlCeCommand insertCommand = new SqlCeCommand(insertString, conn);

                            insertCommand.Parameters.AddWithValue("@nome", textBoxNome.Text);
                            insertCommand.Parameters.AddWithValue("@morada", textBoxMorada.Text);
                            if (textBoxTelefone.Text.ToString().Length > 0)
                            {
                                insertCommand.Parameters.AddWithValue("@telefone", textBoxTelefone.Text);
                            }
                            else
                            {
                                insertCommand.Parameters.AddWithValue("@telefone", DBNull.Value);
                            }
                            if (textBoxTelemovel.Text.ToString().Length > 0)
                            {
                                insertCommand.Parameters.AddWithValue("@telemovel", textBoxTelemovel.Text);
                            }
                            else
                            {
                                insertCommand.Parameters.AddWithValue("@telemovel", DBNull.Value);
                            }
                            if (textBoxEmail.Text.ToString().Length > 0)
                            {
                                insertCommand.Parameters.AddWithValue("@email", textBoxEmail.Text);
                            }
                            else
                            {
                                insertCommand.Parameters.AddWithValue("@email", DBNull.Value);
                            }
                            insertCommand.Parameters.AddWithValue("@numerocontribuinte", textBoxContribuinte.Text);
                            insertCommand.Parameters.AddWithValue("@role_fk", GetUserRoleFk(comboBoxTipoConta.Text));
                            insertCommand.Parameters.AddWithValue("@userid", GetUserId(textBoxUser.Text));

                            insertCommand.ExecuteNonQuery();
                            insertCommand.Parameters.Clear();
                            insertCommand.Dispose();
                            conn.Close();
                        }
                        catch (Exception ex)
                        {
                            MessageBox.Show(ex.Message, "Erro na criação da pessoa!", MessageBoxButtons.OK, MessageBoxIcon.Error);
                            pessoaCriada = false;
                        }


                        /* Se o utilizador foi criado na bd do jardim de infancia é feita a configuração
                         * final da associação da conta de login com a sua role, caso contrário é apagado
                         * o login.
                        */
                        if (pessoaCriada)
                        {
                            LigacaoRoleUser(GetRoleId(comboBoxTipoConta.Text), GetUserId(textBoxUser.Text));
                        }
                        else
                        {
                            Membership.DeleteUser(textBoxUser.Text, true);
                        }
                    }
                }
                else
                {
                    MessageBox.Show("Confirmação da password falhou.\nTente novamente.", "Erro!", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                }
            }

        }

        private void buttonCancel_Click(object sender, EventArgs e)
        {
            Close();
        }


        /// <summary>
        /// Retorna o ID da role na base de dados do jardim de infância que concide com a role dada à conta
        /// </summary>
        /// <param name="role">Role da conta</param>
        /// <returns>ID da rola na base de dados do jardim de infância</returns>
        private int GetUserRoleFk(string role)
        {
            string connectionString = "Data Source=" + _connectionString.GetConnectionStringBd();
            int roleId = 0;
            string query = @"SELECT Role_Id FROM Roles WHERE Nome = '" + role + "'";

            try
            {
                SqlCeConnection conn = new SqlCeConnection(connectionString);
                conn.Open();
                using (SqlCeCommand cmd = new SqlCeCommand(query, conn))
                {
                    using (SqlCeDataReader reader = cmd.ExecuteReader(CommandBehavior.CloseConnection))
                    {
                        reader.Read();
                        roleId = int.Parse(reader[0].ToString());
                        reader.Close();
                    }
                }
                conn.Close();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
            return roleId;
        }


        /// <summary>
        /// Preenche a combobox do tipo de conta com os dados da tabela aspnet_Roles
        /// </summary>
        private void PreencheComboBoxTipoConta()
        {
            try
            {
                string query = @"SELECT RoleName FROM aspnet_Roles";
                SqlConnection conn = new SqlConnection(_connectionString.GetConnectionStringLogin());

                SqlCommand cmd = new SqlCommand(query, conn);

                SqlDataAdapter da = new SqlDataAdapter();
                DataSet ds = new DataSet();

                da.SelectCommand = cmd;

                da.Fill(ds);
                comboBoxTipoConta.DisplayMember = "RoleName";
                comboBoxTipoConta.ValueMember = "RoleName";
                comboBoxTipoConta.DataSource = ds.Tables[0];

            }
            catch (Exception e)
            {
                MessageBox.Show(e.Message);
            }
        }


        /// <summary>
        /// Retorna da base de dados do login o userID do username fornecido.
        /// </summary>
        /// <param name="userName">UserName</param>
        /// <returns>UserID</returns>
        private string GetUserId(string userName)
        {
            //string userId = null;
            //string query = @"SELECT UserId FROM aspnet_Users WHERE UserName = '" + userName + "'";
            //try
            //{
            //    SqlConnection conn = new SqlConnection(_connectionString.GetConnectionStringLogin());
            //    conn.Open();

            //    using (SqlCommand cmd = new SqlCommand(query, conn))
            //    {
            //        using (SqlDataReader reader = cmd.ExecuteReader(CommandBehavior.CloseConnection))
            //        {
            //            reader.Read();
            //            userId = reader[0].ToString();
            //            reader.Close();
            //        }
            //    }
            //    conn.Close();
            //}
            //catch (Exception ex)
            //{
            //    MessageBox.Show("Erro na ligação à base de dados. \nVerifique a configuração.", "Erro!", MessageBoxButtons.OK, MessageBoxIcon.Error);
            //}
            //return userId;
            return Membership.GetUser(userName).ProviderUserKey.ToString();
        }


        /// <summary>
        /// Retorna da base de dados do login a roleID da role fornecida. (Administrador, EE ou Funcionario)
        /// </summary>
        /// <param name="role">Role</param>
        /// <returns>RoleID</returns>
        private string GetRoleId(string role)
        {
            string roleId = null;
            string query = @"SELECT RoleId FROM aspnet_Roles WHERE RoleName = '" + role + "'";
            try
            {
                SqlConnection conn = new SqlConnection(_connectionString.GetConnectionStringLogin());
                conn.Open();

                using (SqlCommand cmd = new SqlCommand(query, conn))
                {
                    using (SqlDataReader reader = cmd.ExecuteReader(CommandBehavior.CloseConnection))
                    {
                        reader.Read();
                        roleId = reader[0].ToString();
                        reader.Close();
                    }
                }
                conn.Close();
            }
            catch (Exception ex)
            {
                MessageBox.Show("Erro na ligação à base de dados. \nVerifique a configuração.", "Erro!", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            return roleId;
        }


        /// <summary>
        /// Insere a associação da role ao user na base de dados do login.
        /// </summary>
        /// <param name="roleId">ID da role</param>
        /// <param name="userId">ID do user</param>
        /// <returns>Retorna true se a associação for bem sucedida.</returns>
        private bool LigacaoRoleUser(string roleId, string userId)
        {
            bool registoBemSucedido = false;
            string insertString = @"INSERT INTO aspnet_UsersInRoles (UserId, RoleId) VALUES (@userid, @roleid)";
            SqlConnection conn = new SqlConnection(_connectionString.GetConnectionStringLogin());
            conn.Open();
            try
            {
                SqlCommand insertCommand = new SqlCommand(insertString, conn);

                insertCommand.Parameters.AddWithValue("@userid", userId);
                insertCommand.Parameters.AddWithValue("@roleid", roleId);

                insertCommand.ExecuteNonQuery();
                insertCommand.Parameters.Clear();
                insertCommand.Dispose();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "Erro!", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            finally
            {
                conn.Close();
                registoBemSucedido = true;
            }
            return registoBemSucedido;
        }


    }
}
